<?php
class web_socketer{
    private $websocket;
    public function __construct() {
        $this->websocket = new swoole_websocket_server("0.0.0.0", 9502);
        $this->websocket->set([
            'worker_num'      => 2, //开启2个worker进程
            'max_request'     => 4, //每个worker进程 max_request设置为4次
            'task_worker_num' => 4, //开启4个task进程
            'dispatch_mode'   => 4, //数据包分发策略 - IP分配
            'daemonize'       => false, //守护进程(true/false)
        ]);
        $this->websocket->on('Start', [$this, 'start']);
        $this->websocket->on('Open', [$this, 'open']);
        $this->websocket->on("Message", [$this, 'message']);
        $this->websocket->on("Close", [$this, 'close']);
        $this->websocket->on("Task", [$this, 'task']);
        $this->websocket->on("Finish", [$this, 'finish']);
        $this->websocket->start();
    }
    public function start($websocket) {
        echo "#### 启动 ####".PHP_EOL;
        echo "SWOOLE 版本".SWOOLE_VERSION . " 服务已启动".PHP_EOL;
        echo "主进程 pid: {$websocket->master_pid}".PHP_EOL;
        echo "管理者 pid: {$websocket->manager_pid}".PHP_EOL;
        echo "########".PHP_EOL;
    }
    public function open($websocket, $request) {
        echo "#### open ####".PHP_EOL;
        echo "server: handshake success with fd{$request->fd}".PHP_EOL;
        $websocket->task([
            'type' => 'login'
        ]);
        echo "########".PHP_EOL;
    }
    public function task($websocket, $task_id, $from_id, $data) {
        echo "#### onTask ####".PHP_EOL;
        echo "#{$websocket->worker_id} onTask: [PID={$websocket->worker_pid}]: task_id={$task_id}".PHP_EOL;
        $msg = '';
        switch ($data['type']) {
            case 'login':
                $msg = '我来了...';
                break;
            case 'speak':
                $msg = $data['msg'];
                break;
        }
        //已经连接的 客户
        foreach ($websocket->connections as $fd) {
            $connectionInfo = $websocket->connection_info($fd);
            if ($connectionInfo['websocket_status'] == 3) {
                $websocket->push($fd, $msg); //长度最大不得超过2M
            }
        }
        $websocket->finish($data);
        echo "########".PHP_EOL.PHP_EOL;
    }
    public function message($websocket, $frame) {
        echo "#### onMessage ####".PHP_EOL;
        echo "receive from fd{$frame->fd}:{$frame->data},opcode:{$frame->opcode},fin:{$frame->finish}".PHP_EOL;
        $websocket->task(['type' => 'speak', 'msg' => $frame->data]);
        echo "########".PHP_EOL.PHP_EOL;
    }
    public function finish($websocket,$task_id, $data) {
        echo "#### onFinish ####".PHP_EOL;
        echo "Task {$task_id} 已完成".PHP_EOL;
        echo "########".PHP_EOL.PHP_EOL;
    }
    public function close($websocket, $fd) {
        echo "#### close ####".PHP_EOL;
        echo "client {$fd} closed".PHP_EOL;
        echo "########".PHP_EOL.PHP_EOL;
    }
}

$web_socketer = new web_socketer();
